<?php

namespace App\Service\Cruise\Mission;

use App\Enums\BaseErrorCode;
use App\Enums\WorkOrder\OrderEnum;
use App\Exceptions\Custom\ResponseHttpException;
use App\Library\FeiShu\SendFs;
use App\Library\Rms\RmsCurl;
use App\Library\Rms\RmsUserApi;
use App\Models\Common\ResourcesModel;
use App\Models\Cruise\CruiseOrderInputModel;
use App\Models\Cruise\CruiseOrderModel;
use App\Models\Cruise\CruiseTaskProjectModel;
use App\Models\Cruise\CruiseTemplateModel;
use App\Models\WorkOrder\WorkOrderApplyMainModel;
use App\Service\BaseService;
use App\Service\Renew\RenewService;
use Kuafu\File\FileUtil;
use Kuafu\File\PrivateFileUtil;
use Kuafu\GeneralFs\BuildFs;

class MybankInputService extends CruiseOrderInputBaseService
{
    private ?CruiseOrderModel $cruiseOrderModel;
    private int               $userId;
    private int               $shopId;

    public function __construct(int $cruiseOrderId, int $userId, int $shopId = 0)
    {
        $this->userId  = $userId;
        $this->orderId = $cruiseOrderId;
        $this->shopId  = $shopId;

        if ($cruiseOrderId) {
            $this->cruiseOrderModel = CruiseOrderModel::query()->where('id', $cruiseOrderId)->first();
            if (!$this->cruiseOrderModel) {
                throw new ResponseHttpException(BaseErrorCode::$ERROR_OCCURRED, null,
                    "不存在的任务ID:{$cruiseOrderId}");
            }
        }

        parent::__construct($cruiseOrderId, CruiseTemplateModel::TYPE_99,
            CruiseTemplateModel::SYS_TEMPLATE_OTHER_MYBANK_REGISTER);
    }

    /**
     * 初始化表单信息
     * @return void
     */
    public function initOrderInput(bool $forceUpdate = false, int $templateId = 0): void
    {
        if (!$templateId) {
            $templateId = CruiseTemplateModel::query()
                                             ->where('type', $this->templateType)
                                             ->where('sysTemplate', $this->sysTemplate)
                                             ->where('status', CruiseTemplateModel::STATUS_ON)
                                             ->value('id') ?? 0;
            if (!$templateId) {
                throw new ResponseHttpException(BaseErrorCode::$ERROR_OCCURRED, null,
                    "获取模板类型对应模板失败:{$this->templateType}");
            }
        }

        $this->cruiseOrderModel = CruiseOrderModel::query()->updateOrCreate([
            'shopId'       => 0,
            'createdByUid' => $this->userId,
            'templateId'   => $templateId
        ], [
            'orderNo'   => '',
            'type'      => $this->templateType,
            'status'    => CruiseOrderModel::STATUS_NOT_SUBMIT,
            'handlerId' => $this->userId,
        ]);
        $this->orderId          = $this->cruiseOrderModel->id;

        // 幂等-不再创建
        if (!$forceUpdate && CruiseOrderInputModel::query()->where('orderId', $this->orderId)
                                                  ->where('templateType', $this->templateType)->count()) {
            return;
        }

        $cruiseOrderInputModel = parent::baseInitOrderInput($templateId);

        // 初始化表单数据
        $this->initUserContentJson($this->shopId, $this->userId, $cruiseOrderInputModel);
    }

    public function getInputObjectFill(): array
    {
        $submit = $this->checkSubmit();

        if ($submit && in_array($this->cruiseOrderModel->status,
                [CruiseOrderModel::STATUS_NOT_SUBMIT, CruiseOrderModel::STATUS_NOT_MODIFY])) {
            $disable = false;
        } else {
            $disable = true;
        }

        $data              = parent::baseGetInputObjectFill($disable);
        $data['submit']    = $submit; // 提交权限
        $data['status']    = $this->cruiseOrderModel->status;
        $data['activeUrl'] = $this->cruiseOrderModel->extraArr['activeUrl'] ?? '';

        return $data;
    }

    /**
     * 是否有提交权限
     * @return bool
     */
    private function checkSubmit(): bool
    {
        return $this->userId == $this->cruiseOrderModel->createdByUid;
    }

    public function saveUserContentJson(string $field, $value, array $auditValue = []): void
    {
        // 状态校验
        if (!in_array($this->cruiseOrderModel->status,
            [CruiseOrderModel::STATUS_NOT_SUBMIT, CruiseOrderModel::STATUS_NOT_MODIFY])) {
            $statusText = CruiseOrderModel::CRUISE_STATUS_MAPPING[$this->cruiseOrderModel->status] ?? '';
            BaseService::throwErr("当前状态: {$statusText}，不允许修改");
        }

        if (!$this->checkSubmit()) {
            BaseService::throwErr('没有提交权限');
        }

        // TODO 最好通过对象来处理 - 就是有点费资源
        $meanType = CruiseTaskProjectModel::query()->where('inputField', $field)->value('meanType') ?? 0;

        // 私有图片处理
        if (in_array($meanType, [
            CruiseTaskProjectModel::MEAN_TYPE_ID_CARD_FRONT_PRIVATE,
            CruiseTaskProjectModel::MEAN_TYPE_ID_CARD_BACK_PRIVATE
        ])) {

            if (isset($value['url'])) {
                $parsed_url   = parse_url($value['url']);
                $value['url'] = ltrim($parsed_url['path'], '/');
            }
        }

        if ($meanType == CruiseTaskProjectModel::MEAN_TYPE_BUSINESS_LICENSE_VALID) {
            if (strpos($value, '长期') === false) {
                $value = mb_substr($value, 11, 10);
            } else {
                $value = '2999-12-31';
            }
        }

        parent::baseSaveUserContentJson($field, $value, $auditValue);
    }

    public function submitOrder(): void
    {
        // 状态校验
        if (!in_array($this->cruiseOrderModel->status,
            [
                CruiseOrderModel::STATUS_NOT_SUBMIT,
                CruiseOrderModel::STATUS_NOT_MODIFY,
                CruiseOrderModel::STATUS_NOT_REVIEW
            ])) {
            $statusText = CruiseOrderModel::CRUISE_STATUS_MAPPING[$this->cruiseOrderModel->status] ?? '';
            BaseService::throwErr("当前状态: {$statusText}，不允许提交");
        }

        // 角色校验
        if (!$this->checkSubmit()) {
            BaseService::throwErr('没有提交权限');
        }

        parent::baseSubmitOrder(true);

        $inputValues = $this->getInputValues();

        $businessLicenseNoPrefix = substr($inputValues['businessLicenseNo'], 0, 2);
        if ($businessLicenseNoPrefix == '91') {
            $merchantType = '03';
        } elseif ($businessLicenseNoPrefix == '92')  {
            $merchantType = '02';
        } else {
            BaseService::throwErr("当前仅支持91和92开头的营业执照号码");
        }

        // 网商注册
        $params = [
            'merchantType'               => $merchantType, // 02个体户 03企业商户
            'merchantName'               => $inputValues['merchantName'],
            'principalPerson'            => $inputValues['name'],
            'principalMobile'            => $inputValues['phone'],
            'principalCertNo'            => $inputValues['idCard'],
            'identificationCardLife'     => $inputValues['idCardValid']['endTime'] ?? '',
            'bussAuthNo'                 => $inputValues['businessLicenseNo'],
            'bussAuthVld'                => $inputValues['businessLicenseValid'],
            'businessLicenseImg'         => $inputValues['businessLicenseImg']['url'],
            'identificationCardBackImg'  => $inputValues['idCardBack']['url'],
            'identificationCardFrontImg' => $inputValues['idCardFront']['url'],
            'from'                       => 'app',
            'bindShopList'               => [],
        ];

        // 测试环境写死，否则网商不通过
        if ($params['merchantType'] == '02' && isTest()) {
            $params['merchantName']    = '床宿淆的店';
            $params['principalMobile'] = '14450763299';
            $params['principalPerson'] = '床宿淆';
            $params['principalCertNo'] = '620103197908042449';
            $params['bussAuthNo']      = '9200097908042449XX';
            $params['bussAuthVld']     = "2099-12-30";
        }

        if ($params['merchantType'] == '03' && isTest()) {
            $params['merchantName']    = '傅架鼓测试的公司';
            $params['principalMobile'] = '17005352050';
            $params['principalPerson'] = '傅架鼓';
            $params['principalCertNo'] = '140102197805226834';
            $params['bussAuthNo']      = '9100097805226834XX';
            $params['bussAuthVld']     = "2099-12-30";
        }

        $response = RmsCurl::getIns()->setTimeOut(15)->do('api/internal/mybank/register', $params, 'POST');

        if (!$response['code']) {

//            preg_match('/code=(.*?),/', $response['msg'], $matches);
//            $error_code = $matches[1] ?? '';
//            if ($error_code == 'LICENSE_FOUR_FACTOR_ERROR') {
//
//            }

            $msg = $response['msg'] ?? '默认异常msg';
            $msg .= PHP_EOL;
            $msg .= PHP_EOL;
            $msg .= json_encode($inputValues, JSON_UNESCAPED_UNICODE);

            BuildFs::newRobot(SendFs::ROBOT_MY_BANK)->setTitleContent("网商注册返回异常", $msg)->send();

            BaseService::throwErr('请检查身份证与营业执照是否相同');
        }

        $outOrderNo = $response['data']['outOrderNo'] ?? '';
        $orderNo    = $response['data']['orderNo'] ?? '';
        $activeUrl  = $response['data']['activeUrl'] ?? '';

        // 提交后干的事
        $this->cruiseOrderModel->status    = CruiseOrderModel::STATUS_NOT_REVIEW;
        $this->cruiseOrderModel->handlerId = 0;
        $this->cruiseOrderModel->extra     = json_encode([
            'outOrderNo' => $outOrderNo,
            'orderNo'    => $orderNo,
            'activeUrl'  => $activeUrl,
        ]);
        $this->cruiseOrderModel->save();
    }

    /**
     * 获取用户表单填写基础信息
     * @return array
     */
    public function getInputValues(): array
    {
        $res = [];

        $lists = $this->getInputObjectFill()['lists'];
        foreach ($lists as $position) {

            foreach ($position['projects'] as $project) {
                switch ($project['meanType'] ?? 0) {
                    case CruiseTaskProjectModel::MEAN_TYPE_NAME:
                        $res['name'] = $project['value'];
                        break;
                    case CruiseTaskProjectModel::MEAN_TYPE_PHONE:
                        $res['phone'] = $project['value'];
                        break;
                    case CruiseTaskProjectModel::MEAN_TYPE_ID_CARD:
                        $res['idCard'] = $project['value'];
                        break;
                    case CruiseTaskProjectModel::MEAN_TYPE_IDENTITY_VALID:
                        $res['idCardValid'] = $project['value'];
                        break;
                    case CruiseTaskProjectModel::MEAN_TYPE_BUSINESS_LICENSE_NO:
                        $res['businessLicenseNo'] = $project['value'];
                        break;
                    case CruiseTaskProjectModel::MEAN_TYPE_BUSINESS_LICENSE_IMG:
                        $res['businessLicenseImg'] = $project['value'];
                        break;
                    case CruiseTaskProjectModel::MEAN_TYPE_BUSINESS_LICENSE_VALID:
                        $res['businessLicenseValid'] = $project['value'];
                        break;
                    case CruiseTaskProjectModel::MEAN_TYPE_ID_CARD_FRONT_PRIVATE:
                        $res['idCardFront'] = $project['value'];
                        break;
                    case CruiseTaskProjectModel::MEAN_TYPE_ID_CARD_BACK_PRIVATE:
                        $res['idCardBack'] = $project['value'];
                        break;
                    case CruiseTaskProjectModel::MEAN_TYPE_MERCHANT_NAME:
                        $res['merchantName'] = $project['value'];
                        break;
                }
            }
        }

        return $res;
    }

    public function audit(array $data): void
    {
        // TODO: Implement audit() method.
    }

    private function initUserContentJson(int $shopId, int $userId, CruiseOrderInputModel $cruiseOrderInputModel)
    {
        $user = (new RmsUserApi())->getUserInfoByIds([$userId])['data'][0] ?? [];

        // 合同中的用户信息
        $contractUserInfo = (new RenewService($shopId))->userInfo();

        // 营业执照
        $archive = self::getBusinessLicense($shopId);

        $userContentJson    = json_decode($cruiseOrderInputModel->userContentJson, true);
        $inputObjectJsonArr = $cruiseOrderInputModel->inputObjectJsonArr;

        foreach ($cruiseOrderInputModel->inputObjectJsonArr as $k1 => $positions) {
            foreach ($positions['projects'] as $k2 => $project) {
                $projectObj = unserialize($project);

                $meanType = $projectObj->meanType;
                $field    = $projectObj->inputName;

                switch ($meanType) {

                    // 当前登录手机号
                    case CruiseTaskProjectModel::MEAN_TYPE_PHONE:
                        $userContentJson[$field] = $user['mobile'];
                        $projectObj->setCustomAttribute(['disabled', true]);
                        break;

                    // 身份证
                    case CruiseTaskProjectModel::MEAN_TYPE_NAME:
                        if ($contractUserInfo) {
                            $userContentJson[$field] = $contractUserInfo['name'] ?? '';
                        }
                        break;

                    case CruiseTaskProjectModel::MEAN_TYPE_ID_CARD:

                        if ($contractUserInfo) {
                            $userContentJson[$field] = $contractUserInfo['idCard'];
                        }
                        break;
                    case CruiseTaskProjectModel::MEAN_TYPE_ID_CARD_FRONT_PRIVATE:

                        if ($contractUserInfo) {
                            $userContentJson[$field] = ['url' => $contractUserInfo['frontSideImg']];
                        }

                        break;
                    case CruiseTaskProjectModel::MEAN_TYPE_ID_CARD_BACK_PRIVATE:

                        if ($contractUserInfo) {
                            $userContentJson[$field] = ['url' => $contractUserInfo['backSideImg']];
                        }
                        break;

                    case CruiseTaskProjectModel::MEAN_TYPE_IDENTITY_VALID:

                        if ($contractUserInfo) {
                            $userContentJson[$field] = [
                                'endTime'   => $contractUserInfo['effectiveEndDate'],
                                'startTime' => $contractUserInfo['effectiveStartDate']
                            ];
                        }
                        break;

                    // 营业执照
                    case CruiseTaskProjectModel::MEAN_TYPE_BUSINESS_LICENSE_IMG:
                        if ($archive) {
                            $userContentJson[$field] = ['url' => $archive['url'] ?? '', 'Name' => $archive['enterpriseName'] ?? ''];
                        }
                        break;

                    case CruiseTaskProjectModel::MEAN_TYPE_BUSINESS_LICENSE_NO:
                        if ($archive) {
                            $userContentJson[$field] = $archive['businessLicenseNumber'] ?? '';
                        }
                        break;
                    case CruiseTaskProjectModel::MEAN_TYPE_BUSINESS_LICENSE_VALID:
                        if ($archive) {
                            $value = ($archive['endTime'] ?? '') ?: '长期有效';

                            if (strpos($value, '长期') === false) {
                                $value = mb_substr($value, 11, 10);
                            } else {
                                $value = '2999-12-31';
                            }

                            $userContentJson[$field] = $value;
                        }
                        break;
                    case CruiseTaskProjectModel::MEAN_TYPE_MERCHANT_NAME:
                        if ($archive) {
                            $userContentJson[$field] = $archive['enterpriseName'] ?? '';
                        }
                        break;
                }

                $inputObjectJsonArr[$k1]['projects'][$k2] = serialize($projectObj);
            }

            $cruiseOrderInputModel->userContentJson = json_encode($userContentJson);
            $cruiseOrderInputModel->inputObjectJson = json_encode($inputObjectJsonArr);
            $cruiseOrderInputModel->save();
        }
    }

    public static function getBusinessLicense(int $shopId)
    {
        $data = [];
        WorkOrderApplyMainModel::query()
                               ->with(['contentRel'])
                               ->where('shopId', $shopId)
                               ->where('problemPid', OrderEnum::PROBLEM_PID_5)
                               ->where('problemChildId', OrderEnum::PROBLEM_PID_5_CHILDREN_105)
                               ->get()
                               ->map(function ($item) use (&$data) {
                                   $contentArr = $item->contentRel->content ? json_decode($item->contentRel->content,
                                       true) : [];

                                   $data = [
                                       'id'                    => $item->contentRel->id ?? 0,
                                       'endTime'               => $contentArr['businessLicenseEndDate'] ?? '',//营业执照有效期
                                       'enterpriseName'        => $contentArr['enterpriseName'] ?? '',       //企业名称
                                       'businessLicenseNumber' => $contentArr['businessLicenseNumber'] ?? '',//统一信用代码
                                   ];
                               }
                               );

        if (isset($data['id']) && $data['id']) {
            ResourcesModel::query()
                          ->where('module', ResourcesModel::MODULE_TYPE_WORK_ORDER)
                          ->where('business', ResourcesModel::BUSINESS_WORK_ORDER_FUNCTION_OPEN)
                          ->where('businessId', $data['id'])
                          ->where('name', 'businessLicenseImg')
                          ->get()
                          ->map(function (ResourcesModel $m) use (&$data) {
                              $data['url'] = $m->isPublic ? (FileUtil::domain() . '/' . ltrim($m->url, '/'))
                                  : PrivateFileUtil::signUrl(ltrim($m->url, '/'));
                          });
        }

        return $data;
    }
}
